using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Alicanto.Helpers
{
    internal class Reflection
    {
        internal static IList<Type> GetParameterTypes(MethodInfo method)
        {
            IList<Type> types = new List<Type>();
            foreach (ParameterInfo parameter in method.GetParameters())
                types.Add(parameter.ParameterType);

            return types;
        }

        internal static MethodInfo ResolveMethodInfo(Type targetType, string methodName, Type[] argumentTypes)
        {
            if (targetType.GetMethod(methodName, argumentTypes) != null)
                return targetType.GetMethod(methodName, argumentTypes);

            // Intensive matching
            MethodInfo[] methods = targetType.GetMethods();
            IList<MethodInfo> matches = new List<MethodInfo>();

            foreach (MethodInfo method in methods)
            {
                if (method.Name == methodName && method.GetParameters().Length == argumentTypes.Length)
                {
                    bool isMatch = false;

                    ParameterInfo[] parameters = method.GetParameters();
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        ParameterInfo parameter = parameters[i];
                        if (parameter.IsOut)
                            break;

                        if (!Typing.IsAssignableFrom(parameter.ParameterType, argumentTypes[i]))
                            break;

                        if (i == parameters.Length - 1)
                            isMatch = true;
                    }

                    if (isMatch)
                        matches.Add(method);
                }
            }

            while (matches.Count > 1)
            {
                MethodInfo a = matches[0];
                MethodInfo b = matches[1];
            }

            if (matches.Count > 0)
                return matches[0];

            return null;
        }
    }
}
